#pragma once
#include"Sem.hpp"
#include"Mutex.hpp"
#include<vector>

static int gnum=5;

template<class T>
class Ringqueue
{
public:
    Ringqueue(int n=gnum)
        :_n(n),
        _rq(n),
        _data_sem(0),
        _space_sem(n),
        _p_step(0),
        _c_step(0)
    {}
    void Pop(T*out)
    {
        _data_sem.P();
        {
            GuardMutex g(&_c_mutex); //这里是一个对象  不是一个函数调用
            *out=_rq[_c_step++];
            _c_step%=_n;
        }
        _space_sem.V();
    }
    void Enqueue(const T& in)
    {
        _space_sem.P();
        {
            GuardMutex g(&_p_mutex);
            _rq[_p_step++]=in;
            _p_step%=_n;
        }
        _data_sem.V();
    }
    ~Ringqueue()
    {}
private:
    std::vector<T> _rq;
    int _n;

    Sem _space_sem;
    Sem _data_sem;

    int _p_step;
    int _c_step;

    Mutex _p_mutex;
    Mutex _c_mutex;
};